﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
using IiiToolkitMain.Common;
using System.Threading.Tasks;
using System.Net.Http;
using IiiToolkitMain.Common.Dto;
using IiiToolkitMain.Controls;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace IiiToolkitMain
{
    public delegate void ClickDelegateHander(object sender, EventArgs e);
    public partial class Video : Form
    {
        public enum PlayerLayout
        {
            One = 1,
            Two = 2,
            Three = 3
        }

        private int index = 1;
        private Image img;
        private UrlModel _urlModel;
        private readonly HkAction _hkAction;
        private VideoPlayer CurrentSelectedPlayer;

        public Video(UrlModel urlModel)
        {
            this._urlModel = urlModel;
            InitializeComponent();

            var appkey = _urlModel.Params["appkey"];
            var secretKey = _urlModel.Params["secret"];
            //var phone = _urlModel.Params["phone"];
            try
            {
                _hkAction = new HkAction(appkey, secretKey);
                _hkAction.msgCallback = MsgCallback;
                var ret = _hkAction.Start(); //进入系统自动初始化库            
                if (!ret)
                {
                    MessageBox.Show(@"初始化失败,请检查参数配置!", @"系统提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
            }
            catch (Exception ex) //出现异常则提示
            {
                MessageBox.Show(@"异常！" + ex.ToString(), @"系统提示", MessageBoxButtons.OK);
                Application.Exit();
            }
        }

        private int MsgCallback(IntPtr sessionId, HkSDK.MessageType msgType, uint errorCode, string info, IntPtr pUser)
        {
            var player = players.FirstOrDefault(x => x.SessionId == sessionId);
            if (player == null) return 0;

            switch ((uint)msgType)
            {
                case 20:
                    JObject obj = (JObject)JsonConvert.DeserializeObject(info);
                    if (errorCode == 0)
                    {
                        //PlayMainWindow.jObjInfo = obj;
                        //PlayMainWindow.isOpertion = 2;
                    }
                    break;
                case 3:// 播放开始
                    player.Status = VideoPlayer.PlayStatus.Playing;
                    break;
                case 4:// 播放终止
                    player.Status = VideoPlayer.PlayStatus.Stoped;
                    break;
                case 5:// 播放结束，回放结束时会有此消息
                    //PlayMainWindow.mType = PlayMainWindow.MessageType.INS_PLAY_ARCHIVE_END;
                    player.Status = VideoPlayer.PlayStatus.Stoped;
                    break;
                default:
                    break;
            }

            return 0;
        }

        private void Video_Load(object sender, EventArgs e)
        {
            this.pageIndex = 1;

            CreatePlayers();
            RedrawPlayer();

            LoadCameras();
        }
        private List<VideoPlayer> players = new List<VideoPlayer>();
        private void CreatePlayers()
        {
            for (int i = 0; i < 9; i++)
            {
                var player = new VideoPlayer
                {
                    Margin = new Padding(1),
                    Dock = DockStyle.Fill,
                    SelectedColor = Color.LightSkyBlue,

                };
                player.ClearSelectedColor();
                player.OnVideoPlayerSelected += PlayerOnVideoPlayerSelected;
                player.OnVideoPlayerStatusChanged += Player_OnVideoPlayerStatusChanged;
                players.Add(player);
            }
        }
        private void PlayerOnVideoPlayerSelected(object sender, EventArgs e)
        {
            foreach (VideoPlayer player in this.tablePlayer.Controls)
            {
                player.ClearSelectedColor();
            }
            CurrentSelectedPlayer = sender as VideoPlayer;
            if (CurrentSelectedPlayer != null)
            {
                CurrentSelectedPlayer.SetSelectedColor();
            }
        }
        private void Player_OnVideoPlayerStatusChanged(object sender, VideoPlayerEventArgs e)
        {
            var player = sender as VideoPlayer;
            if (player != null)
            {
                //if (player == CurrentSelectedPlayer)
                //{
                //this.btnStopPlay.Enabled = player.Status == VideoPlayer.PlayStatus.Playing;
                //}
            }
        }

        private PlayerLayout _playerLayout = PlayerLayout.One; //表示选择的几个窗口播放
        private void RedrawPlayer()
        {
            int count = (int)_playerLayout;
            TableDynamicLayout(tablePlayer, count, count);
            var i = 0;
            for (int row = 0; row < tablePlayer.RowCount; row++)
            {
                for (int col = 0; col < tablePlayer.ColumnCount; col++)
                {
                    var player = players[i++];
                    player.ClearSelectedColor();
                    this.tablePlayer.Controls.Add(player, col, row);
                }
            }
            CurrentSelectedPlayer = players.First();
            CurrentSelectedPlayer.SetSelectedColor();
        }
        /// <summary>  
        /// 动态布局  (行列高宽平均)
        /// </summary>  
        /// <param name="layoutPanel">布局面板</param>  
        /// <param name="row">行</param>  
        /// <param name="col">列</param>  
        private void TableDynamicLayout(TableLayoutPanel layoutPanel, int row, int col)
        {
            this.tablePlayer.Controls.Clear();
            this.tablePlayer.AutoSize = true;
            layoutPanel.RowStyles.Clear();
            layoutPanel.RowCount = row;    //设置分成几行  
            for (int i = 0; i < row; i++)
            {
                layoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100F / row));
            }
            layoutPanel.ColumnStyles.Clear();
            layoutPanel.ColumnCount = col;    //设置分成几列  
            for (int i = 0; i < col; i++)
            {
                layoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F / col));
            }
        }
        //private static Random random = new Random();
        //private Color RandomColor()
        //{
        //    int R = random.Next(255);
        //    int G = random.Next(255);
        //    int B = random.Next(255);
        //    B = (R + G > 400) ? R + G - 400 : B;//0 : 380 - R - G;
        //    B = (B > 255) ? 255 : B;
        //    return Color.FromArgb(R, G, B);
        //}




        private int pageIndex = 1;

        private void LoadCameras()
        {
            if (this.pageIndex <= 1)
            {
                pageIndex = 1;
                this.layoutLeft.Controls.Clear();
            }
            var devicederial = "";
            int channelNo = -1;
            if (_urlModel.Params.ContainsKey("devicederial"))
            {
                devicederial = _urlModel.Params["devicederial"];
            }
            if (_urlModel.Params.ContainsKey("channelno"))
            {
                int.TryParse(_urlModel.Params["channelno"], out channelNo);
            }
            //窗口加载获取accesstoken
            var videoList = _hkAction.GetDeviceList(pageIndex - 1, 10);
            if (videoList.count > 0 && videoList.cameraList != null)
            {
                //foreach (var cameraItem in videoList.cameraList)
                //{
                    var item = new VideoItem(videoList.cameraList.First());
                    var cameraItem =videoList.cameraList.ToList().Find(x => x.cameraId.Equals("837ce0e9e5834648ba673008e9c75135"));
                    item.OnVideoItemSelectedEvent += ItemOnVideoItemSelectedEvent;
                    if (channelNo > 0 && cameraItem.cameraNo == channelNo.ToString() && cameraItem.deviceSerial == devicederial)
                    {
                        ItemOnVideoItemSelectedEvent(players.First(), new VideoItemPlayEventArgs(cameraItem));
                    }
                    this.layoutLeft.Controls.Add(item);
               // }
            }
        }

        /// <summary>
        /// 点击开始播放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ItemOnVideoItemSelectedEvent(object sender, VideoItemPlayEventArgs e)
        {
            if (CurrentSelectedPlayer == null)
            {
                MessageBox.Show("请先选择一个播放窗口!");
                return;
            }
            if (CurrentSelectedPlayer.SessionId != IntPtr.Zero)
            {
                _hkAction.Stop(CurrentSelectedPlayer.SessionId);
                CurrentSelectedPlayer.SessionId = IntPtr.Zero;
            }
            var sessionId = _hkAction.AllocSession();
            var ret = _hkAction.Play(CurrentSelectedPlayer.PlayerHandle, sessionId, e.CameraItem.cameraId, CurrentSelectedPlayer.VideoLevel);
            CurrentSelectedPlayer.SessionId = sessionId;
            CurrentSelectedPlayer.CameraItem = e.CameraItem;
        }
        private void btnStopPlay_Click(object sender, EventArgs e)
        {
            if (CurrentSelectedPlayer != null && CurrentSelectedPlayer.SessionId != IntPtr.Zero)
            {
                _hkAction.Stop(CurrentSelectedPlayer.SessionId);
                CurrentSelectedPlayer.Stop();
                CurrentSelectedPlayer.SessionId = IntPtr.Zero;
            }
        }


        private void btn1x1_Click(object sender, EventArgs e)
        {
            this._playerLayout = PlayerLayout.One;
            RedrawPlayer();
        }

        private void btn2x2_Click(object sender, EventArgs e)
        {
            this._playerLayout = PlayerLayout.Two;
            RedrawPlayer();
        }

        private void btn3x3_Click(object sender, EventArgs e)
        {
            this._playerLayout = PlayerLayout.Three;
            RedrawPlayer();
        }

        private void Video_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                foreach (var player in players)
                {
                    if (player.SessionId != IntPtr.Zero)
                        _hkAction.Stop(player.SessionId);
                }
                _hkAction.Close();
            }
            catch { }
        }
        private void btn1x1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void btn2x2_Paint(object sender, PaintEventArgs e)
        {

        }

        private void btn3x3_Paint(object sender, PaintEventArgs e)
        {

        }

        private void btnPtz_Click(object sender, EventArgs e)
        {
            //if (this.CurrentSelectedPlayer == null || this.CurrentSelectedPlayer.SessionId == IntPtr.Zero)
            //{
            //    MessageBox.Show("请先选择一个正在播放的视频进行控制!");
            //    return;
            //}
            //var ptz = new VideoPtzForm(CurrentSelectedPlayer.SessionId, _hkAction, CurrentSelectedPlayer.CameraItem.deviceSerial, Convert.ToInt32(CurrentSelectedPlayer.CameraItem.cameraNo));

            //ptz.Location = new Point(MousePosition.X, MousePosition.Y - ptz.Height);
            //ptz.ShowDialog(this.btnPtz.Parent);

        }

        private void btnSpeek_Click(object sender, EventArgs e)
        {
            //_hkAction.
        }

        private void btnSpeek_MouseDown(object sender, MouseEventArgs e)
        {
            _hkAction.StartVoiceTalk(CurrentSelectedPlayer.SessionId, CurrentSelectedPlayer.CameraItem.deviceSerial,
                Convert.ToInt32(CurrentSelectedPlayer.CameraItem.cameraNo));
        }

        private void btnSpeek_MouseUp(object sender, MouseEventArgs e)
        {
            _hkAction.StopVoiceTalk(CurrentSelectedPlayer.SessionId);
        }
        private List<CapturePicture> pictures = new List<CapturePicture>();
        private void button1_Click(object sender, EventArgs e)
        {
            //if (pictures.Count > 10)
            //{
            //    MessageBox.Show("您好,最多拍10张!");
            //    return;
            //}
            var dir = new DirectoryInfo("Upload");


            var serverPath = Path.Combine(dir.FullName, DateTime.Now.Date.ToString("yyyy-MM-dd"));//"C:\\Upload\\" + DateTime.Now.Date.ToString("yyyy-MM-dd") + "\\";
            if (!Directory.Exists(serverPath))
            {
                Directory.CreateDirectory(serverPath);
            }
            var savePath = Path.Combine(serverPath, Guid.NewGuid().ToString() + ".png");// serverPath + Guid.NewGuid().ToString() + ".png";
            //SaveFileDialog sfd = new SaveFileDialog();
            //sfd.Filter = "(*.jpg)|*.jpg";
            //sfd.RestoreDirectory = true;//保存对话框是否记忆上次打开的目录
            //if (sfd.ShowDialog() == DialogResult.OK)//点了保存按钮进入 
            //{
            //    savePath = sfd.FileName; //获得文件路径 
            //}
            if (string.IsNullOrEmpty(savePath)) return;
            var ret = _hkAction.CapturePicture(CurrentSelectedPlayer.SessionId, savePath);
            if (ret)//调用SDK截图方法
            {
                var picture = new CapturePicture()
                {
                    CreateTime = DateTime.Now
                };
                picture.SetPicture(savePath);
                picture.Width = pnlCapturePictureList.Width - 24;
                picture.Margin = new Padding(3);
                picture.OnPictureClick += Picture_OnPictureClick;
                pictures.Add(picture);

                DisplayCapturePictures();
                //img = Image.FromFile(@"" + savePath);
                ////switch (index)
                ////{
                ////    case 1:
                ////        picBox1.Image = img;
                ////        picBox1.ImageLocation = savePath;
                ////        break;
                ////    case 2:
                ////        picbox2.Image = img;
                ////        picbox2.ImageLocation = savePath;
                ////        break;
                ////    case 3:
                ////        picbox3.Image = img;
                ////        picbox3.ImageLocation = savePath;
                ////        break;
                ////}
                //PictureBox pic = new PictureBox();
                ////pic.t
                //pic.Top = 170 * (index - 1) + 5 * index;
                //pic.Left = 5;
                //pic.Image = img;
                //pic.ImageLocation = savePath;
                //pic.Name = "picbox" + index;
                //pic.SizeMode = PictureBoxSizeMode.StretchImage;

                //pic.Parent = ImgPl;
                //pic.Click += new EventHandler(picBox_Click);
                //ImgPl.Controls.Add(picture);
                //index++;
            }
            else
            {
                MessageBox.Show("拍照失败", "提示", MessageBoxButtons.OK);
            }
        }

        private void Picture_OnPictureClick(object sender, CapturePictureEventArgs e)
        {
            PictureBox pic = (PictureBox)sender;
            //释放图片资源
            //img.Dispose();
            ImgFrom imgf = new ImgFrom();
            imgf.ShowDialog();
            int num = 0;
            string desc = "";
            if (imgf.DialogResult == DialogResult.OK)
            {
                num = imgf.Num;
                desc = imgf.Desc;
                Upload(num, desc, pic);
            }
        }

        private void DisplayCapturePictures()
        {
            this.pnlCapturePictureList.Controls.Clear();
            var pics = pictures.OrderByDescending(x => x.CreateTime);
            foreach (var capturePicture in pics)
            {
                this.pnlCapturePictureList.Controls.Add(capturePicture);
            }
        }
        private void picBox_Click(object sender, EventArgs e)
        {

            //Pen pen = new Pen(Color.Red);
            //var name = p.Name;
            //Graphics pictureborder = p.CreateGraphics();
            //pictureborder.DrawRectangle(pen, p.ClientRectangle.X, p.ClientRectangle.Y, p.ClientRectangle.X + p.ClientRectangle.Width - 1, p.ClientRectangle.Y + p.ClientRectangle.Height - 1);
            //Control[] otherImg = ImgPl.Controls.Find("picbox", true);
        }



        ///// <summary>
        ///// 上传图片
        ///// </summary>
        ///// <param name="num">星级</param>
        ///// <param name="desc">描述</param>
        private void Upload(int num, string desc, PictureBox pic)
        {
            string result = "上传成功";
            byte[] bytes;
            if (string.IsNullOrEmpty(pic.ImageLocation))
            {
                MessageBox.Show("请选择上传的图片!");
            }
            button1.Enabled = false;
            btnClear.Enabled = false;
            bytes = SaveImage(pic.ImageLocation);
            //向服务器上传图片流
            if (!ImageRequest(bytes, num, desc))
                result = "上传失败";
            button1.Enabled = true;
            btnClear.Enabled = true;
            MessageBox.Show(result);
        }

        public byte[] SaveImage(string path)
        {
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);
            byte[] imgBytes = br.ReadBytes((int)fs.Length);
            return imgBytes;
        }

        /// <summary>
        /// 上传图片流
        /// </summary>
        /// <param name="data"></param>
        /// <param name="num"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        private bool ImageRequest(byte[] data, int num, string desc)
        {
            const string host = "http://106.14.205.120:80";
            const string path = "/ImageManagerApi/GetImageByte";
            string url = host + path;
            HttpWebResponse httpResponse = null;
            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
            httpRequest.Method = "POST";
            string paramStr = string.Format("num={0}&desc={1}", num, desc);
            byte[] paramByte = Encoding.UTF8.GetBytes(paramStr);
            //合并参数和图片byte数据
            byte[] nowBytes = paramByte.Concat(data).ToArray();
            httpRequest.Headers.Add("DataSize", nowBytes.Length.ToString());
            httpRequest.Headers.Add("ParamSize", paramByte.Length.ToString());
            using (Stream stream = httpRequest.GetRequestStream())
            {
                stream.Write(nowBytes, 0, nowBytes.Length);
                stream.Close();
            }
            try
            {
                httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            }
            catch (WebException ex)
            {

                httpResponse = (HttpWebResponse)ex.Response;
            }
            //响应流
            Stream st = httpResponse.GetResponseStream();
            StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8"));
            string result = reader.ReadToEnd();
            if ("ok".Contains(result))
                return true;
            return false;
        }

        private void layoutLeft_Paint(object sender, PaintEventArgs e)
        {

        }

        private void ImgPl_ControlAdded(object sender, ControlEventArgs e)
        {
            //this.ImgPl.VerticalScroll.Enabled = true;
            //this.ImgPl.VerticalScroll.Visible = true;
            //this.ImgPl.Scroll += ImgPl_Scroll;
        }

        void ImgPl_Scroll(object sender, ScrollEventArgs e)
        {
            this.pnlCapturePictureList.VerticalScroll.Value = e.NewValue;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            pictures.Clear();
            DisplayCapturePictures();
        }

        private void splitContainer3_Panel2_Paint(object sender, PaintEventArgs e)
        {

        }

        private void pnlCapturePictureList_ControlAdded(object sender, ControlEventArgs e)
        {
            this.pnlCapturePictureList.VerticalScroll.Enabled = true;
            this.pnlCapturePictureList.Visible = true;
            this.pnlCapturePictureList.Scroll += ImgPl_Scroll;
        }

        private void btnMin_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void btnMax_Click(object sender, EventArgs e)
        {
            WindowState=FormWindowState.Maximized;
        }

        private void btnNor_Click(object sender, EventArgs e)
        {
            WindowState=FormWindowState.Normal;
        }
    }
}
